﻿using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace SoundSystemControls
{
   public partial class OnetimeSoundPanel : UserControl
   {
      private int middleTrackPoint = 51;
           
      [Category("Onetime Sound Data"),
      Description(""),
      DefaultValue("")]
      public string SoundName 
      {
         get
         { 
            return soundNameLabel.Text; 
         }
         set
         {
            soundNameLabel.Text = value;
         }            
      }

      [Category("Onetime Sound Data"),
      Description(""),
      DefaultValue("")]
      public string XmlParameterName
      {
         get
         {
            return xmlParameterNameTextBox.Text;
         }
         set
         {
            xmlParameterNameTextBox.Text = value;
         }
      }

		[Category("Onetime Sound Data"),
		Description(""),
		DefaultValue(0)]
		public double XmlParameterValue
		{
			get
			{
				double value = GetXmlParameterValue();
				return value;
			}
			set
			{
				xmlParameterValueTextBox.Text = value.ToString();
			}
		}

		[Category("Onetime Sound Data"),
		Description(""),
		DefaultValue(0)]
		public double SpecifiedVolume
		{
			get
			{
				double value = GetSpecifiedVolume();
				return value;				
			}
			set
			{
				specifiedVolumeTextBox.Text = value.ToString();
				specifiedVolumeTrackBar.Tag = value;
			}
		}
		
		[Category("Onetime Sound Data"),
		Description(""),
		DefaultValue(0)]
		public double SpecifiedFrequency
		{
			get
			{
				double value = GetSpecifiedFrequency();
				return value;
			}
			set
			{
				specifiedFrequencyTextBox.Text = value.ToString();
				specifiedFrequencyTrackBar.Tag = value;
			}
		}

      [Category("Onetime Sound Data"),
      Description(""),
      DefaultValue(0)]
      public uint MaxDuration
      {
         get
         {
				uint value = GetMaxDuration();
				return value;
         }
         set
         {
            maxDurationTextBox.Text = value.ToString();
         }
      }

      [Category("Onetime Sound Data"),
      Description(""),
      DefaultValue(false)]
      public bool BlockRepeat
      {
         get
         {
            return blockRepeatCheckBox.Checked;
         }
         set
         {
            blockRepeatCheckBox.Checked = value;
         }
      }
		
		[Category("Onetime Sound Data"),
		Description(""),
		DefaultValue("")]
		public string SoundFileLocation
		{
			get
			{
				return soundFileLocationTextBox.Text;
			}
			set
			{
				soundFileLocationTextBox.Text = value;
			}
		}
		
		private double GetXmlParameterValue()
		{
			if (IsUint(xmlParameterValueTextBox.Text))
			{
				return AsDouble(xmlParameterValueTextBox.Text);
			}
			else return 0.0;
		}

		private double GetSpecifiedVolume()
		{
			if (IsUint(specifiedVolumeTextBox.Text))
			{
				return AsDouble(specifiedVolumeTextBox.Text);
			}
			else return 0.0;
		}

		private double GetSpecifiedFrequency()
		{
			if (IsUint(specifiedFrequencyTextBox.Text))
			{
				return AsDouble(specifiedFrequencyTextBox.Text);
			}
			else return 0.0;
		}

		private uint GetMaxDuration()
		{
			if (IsUint(maxDurationTextBox.Text))
			{
				return AsUint(maxDurationTextBox.Text);
			}
			else return 0;
		}

      
      public OnetimeSoundPanel()
      {
         InitializeComponent();
      }
            
      private void txtXmlParameterName_TextChanged(object sender, EventArgs e)
      {
         if (XmlParameterNameChanged != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            XmlParameterNameChanged(sender, eventArgs);
         }
      }

      private void btnSelectSoundFile_Click(object sender, EventArgs e)
      {
         string soundFileLocation = SelectFileWithDialog();
         if (!String.IsNullOrEmpty(soundFileLocation))
         {
            soundFileLocationTextBox.Text = soundFileLocation;
            RaiseSoundFileLocationChangedEvent(sender);
         }
      }

      private string SelectFileWithDialog()
      {
         OpenFileDialog openFileDialog = new OpenFileDialog();
         openFileDialog.CheckPathExists = true;
         openFileDialog.CheckFileExists = true;
         openFileDialog.Multiselect = false;
         openFileDialog.Filter = GetOpenFileDialogFilter();

         DialogResult dialogResult = openFileDialog.ShowDialog();
         if (dialogResult == DialogResult.OK)
         {
            return openFileDialog.FileName;
         }
         else return String.Empty;
      }

      private string GetOpenFileDialogFilter()
      {
         return String.Concat(
                     "Звуковые файлы (все типы)|",
                        "*.asf;*.wm;*.wma;*.wmv;*.wmd;*.wav;*.snd;*.au;*.aif;*.aifc;",
                        "*.aiff;*.wma;*.mp2;*.mp3;*.adts;*.adt;*.aac|",
                     "Файл Windows Media (ASF) (*.asf;*.wm;*.wma;*.wmv;*.wmd)|",
                        "*.asf;*.wm;*.wma;*.wmv;*.wmd|",
                     "Файл аудио Windows (WAV) (*.wav;*.snd;*.au;*.aif;*.aifc;*.aiff;",
                        "*.wma;*.mp2;*.mp3;*.adts;*.adt;*.aac)|",
                        "*.wav;*.snd;*.au;*.aif;*.aifc;*.aiff;*.wma;*.mp2;*.mp3;*.adts;",
                        "*.adt;*.aac|",
                     "Все файлы (*.*)|*.*");
      }

      private void RaiseSoundFileLocationChangedEvent(object sender)
      {
         if (SoundFileLocationChanged != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            SoundFileLocationChanged(sender, eventArgs);
         }
      }
      
      private void txtSoundFileLocation_TextChanged(object sender, EventArgs e)
      {
         if (SoundFileLocationChanged != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            SoundFileLocationChanged(sender, eventArgs);
         }
      }

      private void txtMaxDuration_TextChanged(object sender, EventArgs e)
      {
         if (MaxDurationChanged != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            MaxDurationChanged(sender, eventArgs);
         }
      }

      private void chkBlockRepeat_CheckedChanged(object sender, EventArgs e)
      {
         if (BlockRepeatChanged != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            BlockRepeatChanged(sender, eventArgs);
         }
      }

      private void txtXmlParameterValue_TextChanged(object sender, EventArgs e)
      {
         if (IsProperXmlParameterValue(xmlParameterValueTextBox.Text) && XmlParameterValueChanged != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            XmlParameterValueChanged(sender, eventArgs);
         }
      }

		private bool IsProperXmlParameterValue(string valueInString)
		{
			if (IsZeroOrOne(valueInString) && IsInt(valueInString))
			{
				return true;
			}
			else return false;
		}

		private bool IsZeroOrOne(string valueInString)
		{
			try
			{
				double value = Double.Parse(valueInString);
				if (value == 1 || value == 0)
				{
					return true;
				}
				else return false;
			}
			catch (Exception e)
			{
				return false;
			}
		}

		private bool IsInt(string valueInString)
		{
			int value; 
			return Int32.TryParse(valueInString, out value);			
		}

		private bool IsUint(string valueInString)
		{
			uint value;
			return uint.TryParse(valueInString, out value);
		}

		private int AsInt(string valueInString)
		{
			try
			{
				int value = Int32.Parse(valueInString);
				return value;
			}
			catch (Exception e)
			{
				return 0;
			}
		}

        private uint AsUint(string valueInString)
        {
            try
            {
                uint value = uint.Parse(valueInString);
                return value;
            }
            catch (Exception e)
            {
                return 0;
            }
        }

		private double AsDouble(string valueInString)
		{
			try
			{
				double value = Double.Parse(valueInString);
				return value;
			}
			catch (Exception e)
			{
				return 0.0;
			}
		}

      private void trckVolume_Scroll(object sender, EventArgs e)
      {
         double baseVolume = GetValueLinkedToTagOf(specifiedVolumeTrackBar);
         int trackPoints;
         int currentTrackPoint = specifiedVolumeTrackBar.Value;
         double changePercent;
         if (currentTrackPoint < middleTrackPoint)
         {
            trackPoints = middleTrackPoint - currentTrackPoint;
            changePercent = trackPoints * 0.75;
            specifiedVolumeTextBox.Text = (baseVolume - (changePercent * baseVolume / 100)).ToString();
         }
         else if (currentTrackPoint > middleTrackPoint)
         {
            trackPoints = currentTrackPoint - middleTrackPoint;
            changePercent = trackPoints * 0.75;
            specifiedVolumeTextBox.Text = (baseVolume + (changePercent * baseVolume / 100)).ToString();
         }
         else
         {
            specifiedVolumeTextBox.Text = baseVolume.ToString();
         }
      }

      private void trckFrequency_Scroll(object sender, EventArgs e)
      {
         double baseFrequency = GetValueLinkedToTagOf(specifiedFrequencyTrackBar);
         int trackPoints;
         int currentTrackPoint = specifiedFrequencyTrackBar.Value;
         double changePercent;
         if (currentTrackPoint < middleTrackPoint)
         {
            trackPoints = middleTrackPoint - currentTrackPoint;
            changePercent = trackPoints * 0.75;
            specifiedFrequencyTextBox.Text = (baseFrequency - (changePercent * baseFrequency / 100)).ToString();
         }
         else if (currentTrackPoint > middleTrackPoint)
         {
            trackPoints = currentTrackPoint - middleTrackPoint;
            changePercent = trackPoints * 0.75;
            specifiedFrequencyTextBox.Text = (baseFrequency + (changePercent * baseFrequency / 100)).ToString();
         }
         else 
         {
            specifiedFrequencyTextBox.Text = baseFrequency.ToString();
         }
      }
      
      private double GetValueLinkedToTagOf(TrackBar trackBar)
      {
         return (Double)trackBar.Tag;         
      }
            
      private void btnResetVolumeTrack_Click(object sender, EventArgs e)
      {
         specifiedVolumeTrackBar.Tag = Double.Parse(specifiedVolumeTextBox.Text.Replace('.', ','));
         specifiedVolumeTrackBar.Value = middleTrackPoint;
      }

      private void btnResetFrequencyTrack_Click(object sender, EventArgs e)
      {
         specifiedFrequencyTrackBar.Tag = Double.Parse(specifiedFrequencyTextBox.Text.Replace('.', ','));
         specifiedFrequencyTrackBar.Value = middleTrackPoint;
      }
      
      private void txtVolume_TextChanged(object sender, EventArgs e)
      {
         if (SpecifiedVolumeChanged != null)
         {
            RaiseVolumeChangedEvent(sender);
         }
      }

      private void txtFrequency_TextChanged(object sender, EventArgs e)
      {
         if (SpecifiedFrequencyChanged != null)
         {
            RaiseFrequencyChangedEvent(sender);
         }
      }

      private void RaiseVolumeChangedEvent(object sender)
      {
         OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
         SpecifiedVolumeChanged(sender, eventArgs);
      }

      private void RaiseFrequencyChangedEvent(object sender)
      {
         OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
         SpecifiedFrequencyChanged(sender, eventArgs);
      }
		
		private void stopButton_Click(object sender, EventArgs e)
		{
			RaiseStopEvent();
			ChangeToPlayButton();
		}

      private void playPauseButton_Click(object sender, EventArgs e)
      {
         if (IsPlayButton(sender))
         {
            RaisePlayEvent();
            ChangeToPauseButton();
         }
         else if (IsPauseButton(sender))
         {
            RaisePauseEvent();
            ChangeToPlayButton();
         }
      }

      private bool IsPlayButton(object sender)
      {
         return ((Button)sender).Text.Equals("Воспроизвести");
      }

      private bool IsPauseButton(object sender)
      {
         return ((Button)sender).Text.Equals("Пауза");
      }
		
      private void RaisePlayEvent()
      {
         if (Play != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            Play(this, eventArgs);
         }
      }

		private void RaisePauseEvent()
		{
			if (Pause != null)
			{
				OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
				Pause(this, eventArgs);
			}
		}

      private void RaiseStopEvent()
      {
         if (Stop != null)
         {
            OnetimeSoundPanelEventArgs eventArgs = new OnetimeSoundPanelEventArgs(this);
            Stop(this, eventArgs);
         }
      }

      private void ChangeToPlayButton()
      {
         playPauseButton.Text = "Воспроизвести";
      }

      private void ChangeToPauseButton()
      {
         playPauseButton.Text = "Пауза";
      }
            
      public event OnetimeSoundPanelEventHandler SoundNameChanged;
      public event OnetimeSoundPanelEventHandler XmlParameterNameChanged;
      public event OnetimeSoundPanelEventHandler SoundFileLocationChanged;
      public event OnetimeSoundPanelEventHandler MaxDurationChanged;
      public event OnetimeSoundPanelEventHandler BlockRepeatChanged;
      public event OnetimeSoundPanelEventHandler XmlParameterValueChanged;
      public event OnetimeSoundPanelEventHandler SpecifiedVolumeChanged;
      public event OnetimeSoundPanelEventHandler SpecifiedFrequencyChanged;
      public event OnetimeSoundPanelEventHandler Play;
		public event OnetimeSoundPanelEventHandler Pause;
      public event OnetimeSoundPanelEventHandler Stop;
   }
}
